﻿
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Runtime.Loader;


namespace NetCore.BLL
{
    /// <summary>
    /// 控制器操作类 
    /// </summary>
    public class ControllerHelper
    {
        #region 获取mvc权限
        /// <summary>
        /// 获取 mvc 页面权限
        /// </summary>
        /// <param name="mvcAssembliesPath"></param>
        /// <returns></returns>
        public static List<MenuPageAttribute> GetController()
        {
            #region 通过反射读取Action方法写入对应权限至集合
            List<MenuPageAttribute> authAttributes = new List<MenuPageAttribute>();
            List<string> keys = new List<string>();
          
            //读取当前项目程序集中集成自AdminController的控制器
            if (ApplicationEnvironments.Site.Components.Plug != null && ApplicationEnvironments.Site.Components.Plug.Count > 0)
            {
                foreach (var component in ApplicationEnvironments.Site.Components.Plug)
                {
                    if (keys.Contains(component.Id))
                        continue;
                    keys.Add(component.Id);
                       var result = GetController(component);
                    if (result != null && result.Count > 0)
                    {
                        authAttributes.AddRange(result);
                    }
                    
                }
            }
            return authAttributes;
            #endregion
        }

        /// <summary>
        /// 获取单个dll中的权限
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List<MenuPageAttribute> GetController(SystemComponent component)
        {
            #region 通过反射读取Action方法写入对应权限至集合
            List<MenuPageAttribute> authAttributes = new List<MenuPageAttribute>();
            List<string> keys = new List<string>();
            if (component==null||!component.Opened || string.IsNullOrWhiteSpace(component.Id))//已关闭的组件不在加载
            {
                return null;
            }
         
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(AppDomain.CurrentDomain.BaseDirectory + (!string.IsNullOrWhiteSpace(component.Api) ? component.Api : component.Mvc) );
            var areaController = assembly.GetTypes().Where(x => x.BaseType == (typeof(BaseAreaController))).FirstOrDefault();
            if (areaController != null)
            {
                var parentMenu = new MenuPageAttribute(component.OrderNum, MenuPageAttribute.PAGEPREFIX+ component.Id, component.Name, component.Unique, component.Icon, component.Opened);
                if (!keys.Contains(parentMenu.PageId))
                {
                    keys.Add(parentMenu.PageId);
                    authAttributes.Add(parentMenu);
                }
                var lstPage = assembly.GetTypes().Where(x => x.IsSubclassOf(areaController)).ToList();
                if (lstPage != null && lstPage.Count > 0)
                {
                    foreach (var type in lstPage)
                    {
                        var pageType = type.GetCustomAttribute(typeof(MenuPageAttribute), false);
                        if (pageType != null)
                        {
                            var page = pageType as MenuPageAttribute;
                            if (!page.IsDeleted)
                            {
                                if (keys.Contains(page.PageId))
                                {
                                    continue;
                                }
                                page.ParentId = parentMenu.PageId;
                                page.PageActions = GetActions(type, page.PageId);
                                page.MenuName = type.Name.Replace("Controller", "");
                                page.ParentName = component.Unique;
                                page.OrderNum = parentMenu.OrderNum + page.OrderNum;
                                page.PageId = parentMenu.PageId + page.PageId;
                                if (!keys.Contains(page.PageId))
                                {
                                    keys.Add(page.PageId);
                                    authAttributes.Add(page);
                                }
                            }
                        }
                    }
                }
            }
            return authAttributes;
            #endregion
        }

        /// <summary>
        /// 获取单个控制器中的Actions
        /// </summary>
        /// <param name="controller"></param>
        public static List<BasePermissionAttribute> GetActions(Type controller,string parentid)
        {
            List<BasePermissionAttribute> authAttributes = new List<BasePermissionAttribute>();
            var areaAttr = controller.GetCustomAttribute(typeof(AreaAttribute), true);
            string areaName = "";
            if (areaAttr != null)
            {
                areaName = (areaAttr as AreaAttribute).RouteValue;
            }

            var members = controller.GetMethods().Where(e => e.GetCustomAttribute(typeof(BasePermissionAttribute), true) != null);
            string[] systemAction = { "index", "forgrid" };
            foreach (var member in members)
            {
                if (systemAction.Contains(member.Name.ToLower()))
                {
                    continue;
                }
                //获取功能列表
                var attr = member.GetCustomAttribute(typeof(BasePermissionAttribute), true);
                if (attr == null)
                    continue;
                var auth = attr as BasePermissionAttribute;
                if (string.IsNullOrWhiteSpace(auth.ActionCode) || !string.IsNullOrWhiteSpace(auth.ActionName) || auth.IsParent || auth.NoAccess)
                {
                    continue;
                }
                auth.ActionCode = parentid + "_" + auth.ActionCode;
                auth.AreaName = areaName;
                if (string.IsNullOrWhiteSpace(auth.ActionName))
                {
                    auth.ActionName = member.Name;
                }
                auth.ControllerName = controller.Name.Replace("Controller", "");
                //功能对应的二级菜单
                authAttributes.Add(auth);
               
            }
            return authAttributes;
        }

        #endregion

        #region 获取api
        /// <summary>
        /// 获取api 页面权限
        /// </summary>
        /// <param name="mvcAssembliesPath"></param>
        /// <returns></returns>
        public static List<MenuPageAttribute> GetApiController(List<string> mvcAssembliesPath)
        {
            #region 通过反射读取Action方法写入对应权限至集合
            List<MenuPageAttribute> authAttributes = new List<MenuPageAttribute>();
            List<string> keys = new List<string>();
            //读取当前项目程序集中集成自AdminController的控制器
            if (mvcAssembliesPath != null && mvcAssembliesPath.Count > 0)
            {
                foreach (var file in mvcAssembliesPath)
                {
                    var assembly = Assembly.LoadFrom(file);
                    var lstPage = assembly.GetTypes().Where(x => x.IsSubclassOf(typeof(ControllerBase))).ToList();
                    if (lstPage != null && lstPage.Count > 0)
                    {
                        foreach (var type in lstPage)
                        {
                            var pageType = type.GetCustomAttribute(typeof(MenuPageAttribute), true);
                            if (pageType != null)
                            {
                                var page = pageType as MenuPageAttribute;
                                if (!page.IsDeleted)
                                {
                                    page.ParentId = "";
                                    page.PageActions = GetActions(type, page.PageId);
                                    page.MenuName = type.Name.Replace("Controller", "");
                                    page.ParentName = "";
                                    if (!keys.Contains(page.PageId))
                                    {
                                        keys.Add(page.PageId);
                                        authAttributes.Add(page);
                                    }
                                }

                            }
                        }
                    }



                }
            }
            return authAttributes;
            #endregion
        }

        /// <summary>
        /// 获取单个控制器中的Actions
        /// </summary>
        /// <param name="controller"></param>
        public static List<BasePermissionAttribute> GetApiActions(Type controller, string parentid)
        {
            List<BasePermissionAttribute> authAttributes = new List<BasePermissionAttribute>();
            var areaAttr = controller.GetCustomAttribute(typeof(AreaAttribute), true);
            string areaName = "";
            if (areaAttr != null)
            {
                areaName = (areaAttr as AreaAttribute).RouteValue;
            }

            var members = controller.GetMethods().Where(e => e.GetCustomAttribute(typeof(BasePermissionAttribute), true) != null);
            string[] systemAction = { "index", "forgrid" };
            foreach (var member in members)
            {
                if (systemAction.Contains(member.Name.ToLower()))
                {
                    continue;
                }
                //获取功能列表
                var attr = member.GetCustomAttribute(typeof(BasePermissionAttribute), true);
                if (attr == null)
                    continue;
                var auth = attr as BasePermissionAttribute;
                if (string.IsNullOrWhiteSpace(auth.ActionCode) || !string.IsNullOrWhiteSpace(auth.ActionName) || auth.IsParent || auth.NoAccess)
                {
                    continue;
                }
                auth.ActionCode = parentid + "_" + auth.ActionCode;
                auth.AreaName = areaName;
                if (string.IsNullOrWhiteSpace(auth.ActionName))
                {
                    auth.ActionName = member.Name;
                }
                auth.ControllerName = controller.Name.Replace("Controller", "");
                //功能对应的二级菜单
                authAttributes.Add(auth);

            }
            return authAttributes;
        }

        #endregion
    }
}
